package io.renren.modules.task.wcs;

import com.sun.jna.WString;
import io.renren.modules.task.wcs.enums.IOServerEnum;
import ioserver.IOServerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Vector;
import java.util.concurrent.Callable;

/**
 * @Author: 蔡翔
 * @Date: 2019/10/12 15:28
 * @Version 1.0
 *
 * 这个类 是启动监听 是否堆垛机任务完成。
 *
 */
public class DDJRunnableCallable<T> implements Callable<T> {
    private final static Logger logger = LoggerFactory.getLogger(DDJRunnableCallable.class);


    //IOServerApi ioServerApi = (IOServerApi) SpringContextUtils.getBean("iOServerApi");
    //IOServerService ioServerService = (IOServerService)SpringContextUtils.getBean("iOServerService");
    //ApplicationContext ioServerApi = new AnnotationConfigApplicationContext(IOServerApi.class);
    private IOServerService ioServerService;
    /*
    会报错 空指针异常
    @Autowired
    IOServerBean ioServerBean;*/

    /*
    1.
    在runnerable 中 直接 Autowire 注入也是不行的
    也就是在自定义线程中 注入外部依赖都不能 用 Autowire。 好像用SpringContextUtils也不行

    2. 只能实例化的时候把你需要的 外部依赖给传进去（这个可行）

    @Autowired
    IOServerApi ioServerApi;

    @Autowired
    IOServerService ioServerService;*/

    /**
     *当前层
     **/
    private com.ioserver.bean.Union_DataType.ByValue wscurrentLayer;
    /**
     *当前列（分为A、B）
     **/
    private com.ioserver.bean.Union_DataType.ByValue wscurrentColumn;
    /**
     *当前位置
     **/
    private com.ioserver.bean.Union_DataType.ByValue wscurrentPosition;
    /**
     *当前 堆垛机 是否在停止
     **/
    private com.ioserver.bean.Union_DataType.ByValue wswalkingRun;




    /**
     *  起点
     **/
    /**
     *目标层
     **/
    private Short destinationLayer = null;
    /**
     *目标列
     **/
    private Short destinationColumn = null;

    /**
     * 终点
     **/
    /**
     *取货位(一个位置 对应两列)
     **/
    private Short takePosition = null;

    /**
     * 故障点
     **/

    private boolean wsWalking_Fault;
    private boolean wsLift_Fault;
    private boolean wsFork_Fault;
    private boolean wsConflict_Fault;


    /**
     * 优雅关闭
     **/
    private boolean switchs = true;


    public DDJRunnableCallable(Short destinationLayer, Short destinationColumn, Short takePosition, IOServerService ioServerService) {
        this.destinationLayer = destinationLayer;
        this.destinationColumn = destinationColumn;
        this.takePosition = takePosition;
        this.ioServerService = ioServerService;
    }

    @Override
    public T call() throws Exception {

        // 订阅所有变量
        Vector<WString> allTagName = ioServerService.getAllTagName();
        logger.info("所有变量："+allTagName);
        Integer flag = -1;
        //while (true && switchs){
        while (true){
            //logger.info("i am Listening");
            wswalkingRun = ioServerService.getValueByName(IOServerEnum.Walking_Run.getCollectionPointName());
            // 报错点
            wsWalking_Fault = ioServerService.getValueByName(IOServerEnum.Walking_Fault.getCollectionPointName()).bitVal;
            wsLift_Fault = ioServerService.getValueByName(IOServerEnum.Lift_Fault.getCollectionPointName()).bitVal;
            wsFork_Fault = ioServerService.getValueByName(IOServerEnum.Fork_Fault.getCollectionPointName()).bitVal;
            wsConflict_Fault = ioServerService.getValueByName(IOServerEnum.Conflict_Fault.getCollectionPointName()).bitVal;

            if(wsWalking_Fault || wsLift_Fault || wsFork_Fault || wsConflict_Fault ){
                flag = 3;
                break;
            }

            if(!wswalkingRun.bitVal){
                //false 表示为 停止
                try {
                    wscurrentLayer = ioServerService.getValueByName(IOServerEnum.Current_Layer.getCollectionPointName());
                    wscurrentColumn = ioServerService.getValueByName(IOServerEnum.Current_Column.getCollectionPointName());
                    wscurrentPosition = ioServerService.getValueByName(IOServerEnum.Current_Position.getCollectionPointName());
                } catch (Exception e) {
                    e.printStackTrace();
                }

                if(wscurrentLayer.i2Val.equals(destinationLayer) && wscurrentColumn.i2Val.equals(destinationColumn)){
                    //todo  放货成功后，写入日志（plc点表缺乏一个 完成任务成功的标志）
                    flag =1 ;
                    break;
                }
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
                logger.error("类名：DDJRunnableCallable<T>，线程名："+Thread.currentThread().getName()+"-线程意外退出了");
                break;
            }
        }

        // 0 代表 失败（其他错误） ； 1 代表成功  ; 3 代表设备报错
        if(flag ==1 ){
            logger.info("堆垛机已近完成任务。");
            return (T) new Integer(1);
        }else if(flag == 3){
            logger.error("类名：DDJRunnableCallable<T>，165行代码，堆垛机设备出现故障。");
            return (T) new Integer(3);
        }else {
            logger.error("类名：DDJRunnableCallable<T>，168行代码，未知异常。");
            return (T) new Integer(0);
        }
    }

    public boolean isSwitchs() {
        return switchs;
    }

    public void setSwitchs(boolean switchs) {
        this.switchs = switchs;
    }

    public void shutdownGreaceful(){
        this.switchs = false;
    }

    public Short getDestinationLayer() {
        return destinationLayer;
    }

    public void setDestinationLayer(Short destinationLayer) {
        this.destinationLayer = destinationLayer;
    }

    public Short getDestinationColumn() {
        return destinationColumn;
    }

    public void setDestinationColumn(Short destinationColumn) {
        this.destinationColumn = destinationColumn;
    }

    public Short getTakePosition() {
        return takePosition;
    }

    public void setTakePosition(Short takePosition) {
        this.takePosition = takePosition;
    }


}
